<template>
  <div class="wifi" :title="title" @click.stop>
    <svg :width="size" :height="size * 0.72" viewBox="0 0 28 20" fill="none" xmlns="http://www.w3.org/2000/svg">
      <path :class="['arc', strength >= 1 ? 'on' : 'off']" d="M14 18.5C15 18.5 16 17.5 16 16.5C16 15.5 15 14.5 14 14.5C13 14.5 12 15.5 12 16.5C12 17.5 13 18.5 14 18.5Z" />
      <path :class="['arc', strength >= 2 ? 'on' : 'off']" d="M6 14.5C9.5 11 18.5 11 22 14.5" />
      <path :class="['arc', strength >= 3 ? 'on' : 'off']" d="M2.5 11C7 6.5 21 6.5 25.5 11" />
      <path :class="['arc', strength >= 4 ? 'on' : 'off']" d="M0.5 7C6.5 1 21.5 1 27.5 7" />
    </svg>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, onBeforeUnmount, computed } from 'vue'
import { useNetwork } from '@vueuse/core'

const props = defineProps<{ size?: number }>()
const size = computed(() => props.size ?? 22)

const strength = ref(4) // 0-4
const isEthernet = ref(false)
const net = useNetwork()

function evaluateStrength() {
  if (!net.isOnline.value) {
    strength.value = 0
    return
  }
  const anyNav: any = navigator as any
  const conn = anyNav.connection || anyNav.mozConnection || anyNav.webkitConnection
  // Default optimistic
  let next = 4
  const typeRaw: any = (conn && (conn.type || conn.connectionType)) || net.type.value || ''
  const type = String(typeRaw || '').toLowerCase()
  if (type) {
    if (/ethernet|wired/.test(type)) {
      isEthernet.value = true
      next = 4
    } else if (/wifi/.test(type)) {
      isEthernet.value = false
      // Try downlink (Mbps)
      const down = Number((conn && conn.downlink) || net.downlink.value || 0)
      if (down > 0) {
        if (down >= 20) next = 4
        else if (down >= 10) next = 3
        else if (down >= 2) next = 2
        else next = 1
      } else if (conn && conn.effectiveType) {
        const et = String(conn.effectiveType)
        if (et === '4g') next = 4
        else if (et === '3g') next = 3
        else next = 2
      } else {
        next = 4
      }
    } else {
      // Unknown type but online：假定较好网络
      isEthernet.value = false
      next = 4
    }
  } else if (conn) {
    // 无类型但有连接对象，根据 downlink/effectiveType 估计
    const down = Number(conn.downlink || net.downlink.value || 0)
    if (down >= 20) next = 4
    else if (down >= 10) next = 3
    else if (down >= 2) next = 2
    else if (down > 0) next = 1
    else next = 4
  }
  strength.value = next
}

function setupListeners() {
  const anyNav: any = navigator as any
  const conn = anyNav?.connection || anyNav?.mozConnection || anyNav?.webkitConnection
  if (conn && typeof conn.addEventListener === 'function') {
    conn.addEventListener('change', evaluateStrength)
  } else if (conn && typeof conn.onchange !== 'undefined') {
    conn.onchange = evaluateStrength
  }
  window.addEventListener('online', evaluateStrength)
  window.addEventListener('offline', evaluateStrength)
}

function removeListeners() {
  const anyNav: any = navigator as any
  const conn = anyNav?.connection || anyNav?.mozConnection || anyNav?.webkitConnection
  if (conn && typeof conn.removeEventListener === 'function') {
    conn.removeEventListener('change', evaluateStrength)
  } else if (conn && typeof conn.onchange !== 'undefined') {
    try { conn.onchange = null } catch {}
  }
  window.removeEventListener('online', evaluateStrength)
  window.removeEventListener('offline', evaluateStrength)
}

onMounted(() => {
  evaluateStrength()
  setupListeners()
})
onBeforeUnmount(removeListeners)

const title = computed(() => {
  if (!navigator.onLine) return '未连接'
  if (isEthernet.value) return '有线网络 · 满格'
  return `Wi‑Fi · 信号等级 ${strength.value}/4`
})
</script>

<style scoped>
.wifi { display: inline-flex; align-items: center; }
.arc { stroke: currentColor; stroke-width: 2; stroke-linecap: round; fill: none; opacity: 0.35; }
.on { opacity: 1; }
.off { opacity: 0.15; }
</style>


